﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using GraphDrawer.GraphProvider;

namespace GraphDrawer {
	public partial class ModelEditor : UserControl {
		private double ParentHeight = 250.0;
		private double ParentWidth = 200.0;

		private Boolean isMouseCaptured = false;
		private double mouseVerticalPosition;
		private double mouseHorizontalPosition;

		private Boolean isDrawingConnection = false;
		private double StartMouseVerticalPosition;
		private double StartMouseHorizontalPosition;

		private Connector lastConector;
		private ModelEdge lineCanvas;
		private ModelNode StartNode;
		private Canvas SelectedElement;
		private Brush normalBrush = new SolidColorBrush(Colors.Black);
		private Brush highlightedBrush = new SolidColorBrush(Colors.Yellow);

		private GraphProvider.DiseaseModelGraph graph = new GraphDrawer.GraphProvider.DiseaseModelGraph();
		private GraphProvider.SimpleDiseaseModelEdge lastEdge;
		public String GraphML;

		public String StartState = String.Empty;

		public ModelEditor() {
			InitializeComponent();
			popup.Closed += new RoutedEventHandler(popup_Closed);
			popup.OK += new RoutedEventHandler(popup_OK);
			edgePopUp.OK += new RoutedEventHandler(edge_OK);
			edgePopUp.Closed += new RoutedEventHandler(edge_Closed);
			export.Closed += new RoutedEventHandler(export_Closed);
			export.OK += new RoutedEventHandler(export_OK);
			App.Current.Host.Content.IsFullScreen = false;
			WizardMenu.graphProvider.GetDiseaseModelStateNamesCompleted += new EventHandler<GetDiseaseModelStateNamesCompletedEventArgs>(graphProvider_GetDiseaseModelStateNamesCompleted);
			WizardMenu.graphProvider.GetDiseaseModelStateNamesAsync();
		}

		void graphProvider_GetDiseaseModelStateNamesCompleted(object sender, GetDiseaseModelStateNamesCompletedEventArgs e) {
			foreach (var item in e.Result) {
				popup.ComboBoxStateNames.Items.Add(item);
			}
			popup.ComboBoxStateNames.SelectedIndex = 0;
		}

		public String CreateGraphML() {

			GraphML.graphml g = new GraphDrawer.GraphML.graphml();
			g.key = new GraphDrawer.GraphML.graphmlKey[4];
			g.key[0] = new GraphDrawer.GraphML.graphmlKey();
			g.key[0].id = "stateName";
			g.key[0].@for = "node";
			g.key[0].attrname = "stateName";
			g.key[0].attrtype = "string";

			g.key[1] = new GraphDrawer.GraphML.graphmlKey();
			g.key[1].id = "stateClass";
			g.key[1].@for = "node";
			g.key[1].attrname = "stateClass";
			g.key[1].attrtype = "string";

			g.key[2] = new GraphDrawer.GraphML.graphmlKey();
			g.key[2].id = "nodeColor";
			g.key[2].@for = "node";
			g.key[2].attrname = "nodeColor";
			g.key[2].attrtype = "string";

			g.key[3] = new GraphDrawer.GraphML.graphmlKey();
			g.key[3].id = "probability";
			g.key[3].@for = "edge";
			g.key[3].attrname = "probability";
			g.key[3].attrtype = "double";

			g.graph = new GraphDrawer.GraphML.graphmlGraph();
			g.graph.id = "G";
			g.graph.parseorder = "nodesfirst";
			g.graph.parseedgeids = "free";
			g.graph.parsenodeids = "free";
			g.graph.edgedefault = "directed";

			g.graph.parseedges = graph.Edges.Count;
			g.graph.parsenodes = graph.Vertices.Count;

			g.graph.node = new GraphDrawer.GraphML.graphmlGraphNode[g.graph.parsenodes];
			g.graph.edge = new GraphDrawer.GraphML.graphmlGraphEdge[g.graph.parseedges];

			for (int i = 0; i < graph.Vertices.Count; i++) {
				var node = new GraphDrawer.GraphML.graphmlGraphNode();

				node.id = graph.Vertices[i].stateName;


				List<GraphDrawer.GraphML.graphmlGraphNodeData> datas = new List<GraphDrawer.GraphML.graphmlGraphNodeData>();
				foreach (var item in g.key) {
					if (item.@for == "node") {
						var data = new GraphDrawer.GraphML.graphmlGraphNodeData();
						data.key = item.attrname;
						data.Value = graph.Vertices[i].GetType().GetProperty(item.attrname).GetValue(graph.Vertices[i], null).ToString();
						datas.Add(data);
					}
				}

				node.data = datas.ToArray();
				g.graph.node[i] = node;
			}

			for (int i = 0; i < graph.Edges.Count; i++) {
				var edge = new GraphDrawer.GraphML.graphmlGraphEdge();

				SilverLightDiseaseModelNode source = null;
				SilverLightDiseaseModelNode target = null;

				foreach (var item in graph.Vertices) {
					if (item.Id == graph.Edges[i].Source) {
						source = item;
					}
					if (item.Id == graph.Edges[i].Target) {
						target = item;
					}

					if (source != null & target != null)
						break;
				}

				edge.id = source.stateName + "->" + target.stateName;
				edge.source = source.stateName;
				edge.target = target.stateName;


				List<GraphDrawer.GraphML.graphmlGraphEdgeData> datas = new List<GraphDrawer.GraphML.graphmlGraphEdgeData>();
				foreach (var item in g.key) {
					if (item.@for == "edge") {
						var data = new GraphDrawer.GraphML.graphmlGraphEdgeData();
						data.key = item.attrname;
						data.Value = graph.Edges[i].GetType().GetProperty(item.attrname).GetValue(graph.Edges[i], null).ToString();
						datas.Add(data);
					}
				}

				edge.data = datas.ToArray();
				g.graph.edge[i] = edge;
			}

			System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(g.GetType());
			System.IO.StringWriter writer = new System.IO.StringWriter();
			ser.Serialize(writer, g);

			return writer.ToString();
		}

		#region PopUps events
		#region Edge PopUp
		void edge_Closed(object sender, RoutedEventArgs e) {
			lastEdge = null;
			lastConector = null;
			lineCanvas = null;
		}

		void edge_OK(object sender, RoutedEventArgs e) {
			lastEdge = new SimpleDiseaseModelEdge();

			lastEdge.probability = edgePopUp.Probability;
			lastEdge.Source = StartNode.node.Id;
			lastEdge.Target = ((ModelNode)lastConector.Parent).node.Id;
			if (graph.Edges == null)
				graph.Edges = new System.Collections.ObjectModel.ObservableCollection<SimpleDiseaseModelEdge>();
			graph.Edges.Add(lastEdge);

			lineCanvas.edge = lastEdge;

			lastEdge = null;
			lastConector = null;
			lineCanvas = null;
		}
		#endregion

		#region Node PopUp
		void popup_OK(object sender, RoutedEventArgs e) {
			//TODO: show question about probability and Name                     
			int selectorHeight = 5;
			int selectorWidth = 5;

			Canvas RectWithTitle = CreateRectangleWithTitle(popup.NodeName, popup.NodeColor);
			Canvas selectorCanvasLeft = CreateConnector(selectorHeight, selectorWidth);
			Canvas selectorCanvasRight = CreateConnector(selectorHeight, selectorWidth);
			Canvas selectorCanvasTop = CreateConnector(selectorHeight, selectorWidth);
			Canvas selectorCanvasBootom = CreateConnector(selectorHeight, selectorWidth);

			RectWithTitle.SetValue(Canvas.LeftProperty, selectorCanvasLeft.Width / 2.0);
			RectWithTitle.SetValue(Canvas.TopProperty, selectorCanvasLeft.Height / 2.0);

			selectorCanvasLeft.SetValue(Canvas.LeftProperty, 0.0);
			selectorCanvasLeft.SetValue(Canvas.TopProperty, RectWithTitle.Height / 2.0);

			selectorCanvasRight.SetValue(Canvas.LeftProperty, RectWithTitle.Width);
			selectorCanvasRight.SetValue(Canvas.TopProperty, RectWithTitle.Height / 2.0);

			selectorCanvasTop.SetValue(Canvas.LeftProperty, RectWithTitle.Width / 2.0);
			selectorCanvasTop.SetValue(Canvas.TopProperty, 0.0);

			selectorCanvasBootom.SetValue(Canvas.LeftProperty, RectWithTitle.Width / 2.0);
			selectorCanvasBootom.SetValue(Canvas.TopProperty, RectWithTitle.Height);

			ModelNode element = new ModelNode() {
				Width = RectWithTitle.Width + selectorWidth,
				Height = RectWithTitle.Height + selectorHeight
			};

			element.border = RectWithTitle.Children[0] as Rectangle;

			element.MouseLeftButtonDown += new MouseButtonEventHandler(Handle_MouseDown);
			element.MouseLeftButtonUp += new MouseButtonEventHandler(Handle_MouseUp);
			element.MouseMove += new MouseEventHandler(Handle_MouseMove);

			element.Children.Add(RectWithTitle);
			element.Children.Add(selectorCanvasLeft);
			element.Children.Add(selectorCanvasRight);
			element.Children.Add(selectorCanvasTop);
			element.Children.Add(selectorCanvasBootom);

			element.connectors.Add(selectorCanvasLeft as Connector);
			element.connectors.Add(selectorCanvasRight as Connector);
			element.connectors.Add(selectorCanvasTop as Connector);
			element.connectors.Add(selectorCanvasBootom as Connector);

			element.SetValue(Canvas.LeftProperty, ParentWidth / 2.0 - element.Width);
			element.SetValue(Canvas.TopProperty, ParentHeight / 2.0 - element.Height);


			var node = new SilverLightDiseaseModelNode();
			node.Id = node.GetHashCode();
			node.stateName = popup.NodeName;
			node.stateClass = popup.StateClass;
			node.nodeColor = popup.NodeColor.ToString();
			if (graph.Vertices == null)
				graph.Vertices = new System.Collections.ObjectModel.ObservableCollection<SilverLightDiseaseModelNode>();
			graph.Vertices.Add(node);

			element.node = node;

			if (popup.StartState.IsChecked.HasValue) {
				if (popup.StartState.IsChecked.Value)
					StartState = popup.NodeName;
			}

			rootCanvas.Children.Add(element);
		}

		void popup_Closed(object sender, RoutedEventArgs e) {

		}
		#endregion
		#endregion

		#region Export PopUp
		void export_OK(object sender, RoutedEventArgs e) {

		}

		void export_Closed(object sender, RoutedEventArgs e) {

		}
		#endregion

		#region Selector Events
		void selectorCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
			lastConector.ReleaseMouseCapture();

			Boolean isOnConnector = false;

			foreach (var item in rootCanvas.Children) {
				if (item is ModelNode) {
					ModelNode model = item as ModelNode;
					foreach (var connectorTOCheck in model.connectors) {
						Point p = e.GetPosition(connectorTOCheck);
						double x1 = 0;
						double x2 = connectorTOCheck.Width;
						double y1 = 0;
						double y2 = connectorTOCheck.Height;

						if ((p.X >= x1 && p.X <= x2) &&
							(p.Y >= y1 && p.Y <= y2)) {
							isOnConnector = true;
							connectorTOCheck.lines.Add(lineCanvas, true);
							lastConector = connectorTOCheck;
							edgePopUp.Height = App.Current.Host.Content.ActualHeight;
							edgePopUp.Width = App.Current.Host.Content.ActualWidth;
							edgePopUp.SetValue(Canvas.ZIndexProperty, 15);
							edgePopUp.Visibility = Visibility.Visible;

							break;
						}
					}
				}
			}



			if (!isOnConnector) {
				rootCanvas.Children.Remove(lineCanvas);

				lastEdge = null;
				lastConector = null;
				lineCanvas = null;
			}

			mouseVerticalPosition = -1;
			mouseHorizontalPosition = -1;

			isDrawingConnection = false;

		}

		void selectorCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
			isMouseCaptured = false;
			isDrawingConnection = true;
			lastConector = sender as Connector;

			StartNode = lastConector.Parent as ModelNode;

			mouseVerticalPosition = e.GetPosition(rootCanvas).Y;
			mouseHorizontalPosition = e.GetPosition(rootCanvas).X;

			StartMouseVerticalPosition = e.GetPosition(this).Y;
			StartMouseHorizontalPosition = e.GetPosition(this).X;

			isMouseCaptured = true;
			lastConector.CaptureMouse();
		}

		void selectorCanvas_MouseLeave(object sender, MouseEventArgs e) {
			Canvas canvas = sender as Canvas;
			ScaleTransform t = new ScaleTransform();
			t.CenterX = canvas.Width / 2.0;
			t.CenterY = canvas.Height / 2.0;
			t.ScaleX = 1.0;
			t.ScaleY = 1.0;

			canvas.RenderTransform = t;
		}

		void selectorCanvas_MouseEnter(object sender, MouseEventArgs e) {
			Canvas canvas = sender as Canvas;

			ScaleTransform t = new ScaleTransform();
			t.CenterX = canvas.Width / 2.0;
			t.CenterY = canvas.Height / 2.0;
			t.ScaleX = 2.0;
			t.ScaleY = 2.0;

			canvas.RenderTransform = t;
		}
		#endregion

		#region Nodes events
		void Handle_MouseDown(object sender, MouseButtonEventArgs e) {
			if (!isDrawingConnection) {
				ModelNode item = sender as ModelNode;

				RemoveHighlight();

				SelectedElement = item;
				ModelNode model = SelectedElement as ModelNode;
				model.border.Stroke = highlightedBrush;

				mouseVerticalPosition = e.GetPosition(null).Y;
				mouseHorizontalPosition = e.GetPosition(null).X;
				isMouseCaptured = true;
				item.CaptureMouse();
			}

		}

		void Handle_MouseUp(object sender, MouseButtonEventArgs e) {
			if (!isDrawingConnection) {
				Canvas item = sender as Canvas;
				isMouseCaptured = false;
				item.ReleaseMouseCapture();
				mouseVerticalPosition = -1;
				mouseHorizontalPosition = -1;
			}

		}

		void Handle_MouseMove(object sender, MouseEventArgs e) {
			Canvas item = sender as Canvas;
			if (isMouseCaptured && !isDrawingConnection) {

				// Calculate the current position of the object.
				double deltaV = e.GetPosition(null).Y - mouseVerticalPosition;
				double deltaH = e.GetPosition(null).X - mouseHorizontalPosition;
				double newTop = deltaV + (double)item.GetValue(Canvas.TopProperty);
				double newLeft = deltaH + (double)item.GetValue(Canvas.LeftProperty);

				foreach (var child in item.Children) {
					if (child is Connector) {
						Connector connector = child as Connector;
						foreach (var pair in connector.lines) {
							var canvas = pair.Key;

							canvas.Height += deltaV;
							canvas.Width += deltaH;

							Line line = canvas.line;

							double x1 = (double)item.GetValue(Canvas.LeftProperty);
							double x2 = x1 + item.Width;
							double y1 = (double)item.GetValue(Canvas.TopProperty);
							double y2 = y1 + item.Height;

							if (pair.Value) {
								line.X2 += deltaH;
								line.Y2 += deltaV;
							}
							else {
								line.X1 += deltaH;
								line.Y1 += deltaV;
							}

							StartMouseHorizontalPosition = line.X1;
							StartMouseVerticalPosition = line.Y1;
							mouseHorizontalPosition = line.X2;
							mouseVerticalPosition = line.Y2;
							Point l1;
							Point l2;
							GetArrow(out l1, out l2);

							canvas.lineArrow.Points.Clear();
							//TODO: arrow
							canvas.lineArrow.Points.Add(new Point(mouseHorizontalPosition, mouseVerticalPosition));
							canvas.lineArrow.Points.Add(new Point(l1.X, l1.Y));
							canvas.lineArrow.Points.Add(new Point(l2.X, l2.Y));
						}
					}
				}

				// Set new position of object.
				item.SetValue(Canvas.TopProperty, newTop);
				item.SetValue(Canvas.LeftProperty, newLeft);

				// Update position global variables.
				mouseVerticalPosition = e.GetPosition(null).Y;
				mouseHorizontalPosition = e.GetPosition(null).X;
			}
			if (isDrawingConnection) {
				if (lineCanvas == null) {

					var line = new Line {
						X1 = StartMouseHorizontalPosition,
						Y1 = StartMouseVerticalPosition,
						X2 = mouseHorizontalPosition,
						Y2 = mouseVerticalPosition,
						Stroke = new SolidColorBrush(Colors.Black),
						StrokeThickness = 3
					};



					Polygon lineArrow = new Polygon();
					lineArrow.Points = new PointCollection();
					lineArrow.Fill = new SolidColorBrush(Colors.Black);
					Point l1;
					Point l2;
					GetArrow(out l1, out l2);

					//TODO: arrow
					lineArrow.Points.Add(new Point(mouseHorizontalPosition, mouseVerticalPosition));
					lineArrow.Points.Add(new Point(l1.X, l1.Y));
					lineArrow.Points.Add(new Point(l2.X, l2.Y));

					lineCanvas = new ModelEdge() {
						Height = line.Height,
						Width = line.Width
					};

					lineCanvas.MouseLeftButtonDown += new MouseButtonEventHandler(lineCanvas_MouseLeftButtonDown);

					lineCanvas.line = line;
					lineCanvas.lineArrow = lineArrow;

					lineCanvas.Children.Add(line);
					lineCanvas.Children.Add(lineArrow);
					rootCanvas.Children.Add(lineCanvas);

					lastConector.lines.Add(lineCanvas, false);
				}
				else {
					lineCanvas.line.X2 = mouseHorizontalPosition;
					lineCanvas.line.Y2 = mouseVerticalPosition;

					Point l1;
					Point l2;
					GetArrow(out l1, out l2);


					lineCanvas.lineArrow.Points.Clear();
					//TODO: arrow
					lineCanvas.lineArrow.Points.Add(new Point(mouseHorizontalPosition, mouseVerticalPosition));
					lineCanvas.lineArrow.Points.Add(new Point(l1.X, l1.Y));
					lineCanvas.lineArrow.Points.Add(new Point(l2.X, l2.Y));

					lineCanvas.Height = lineCanvas.line.Height;
					lineCanvas.Width = lineCanvas.line.Width;
				}

				mouseVerticalPosition = e.GetPosition(rootCanvas).Y;
				mouseHorizontalPosition = e.GetPosition(rootCanvas).X;


			}
		}

		private void GetArrow(out Point p1, out Point p2) {
			RotateTransform rot1 = new RotateTransform();
			rot1.Angle = 45.0;
			rot1.CenterX = mouseHorizontalPosition;
			rot1.CenterY = mouseVerticalPosition;

			RotateTransform rot2 = new RotateTransform();
			rot2.Angle = -45.0;
			rot2.CenterX = mouseHorizontalPosition;
			rot2.CenterY = mouseVerticalPosition;


			//ScaleTransform scl = new ScaleTransform();
			//TODO: set const scale :P
			//scl.ScaleX = 0.2;
			//scl.ScaleY = 0.2;
			//scl.CenterX = mouseHorizontalPosition;
			//scl.CenterY = mouseVerticalPosition;            

			//p1 = rot1.Transform(new Point(StartMouseHorizontalPosition, StartMouseVerticalPosition));
			//p2 = rot2.Transform(new Point(StartMouseHorizontalPosition, StartMouseVerticalPosition));

			//p1 = scl.Transform(p1);
			//p2 = scl.Transform(p2);

			// Const size of the arrow
			double px = StartMouseHorizontalPosition - mouseHorizontalPosition;
			double py = StartMouseVerticalPosition - mouseVerticalPosition;
			double d = Math.Sqrt(px * px + py * py);
			px /= d;
			py /= d;
			p1 = rot1.Transform(new Point(mouseHorizontalPosition + 15 * px, mouseVerticalPosition + 15 * py));
			p2 = rot2.Transform(new Point(mouseHorizontalPosition + 15 * px, mouseVerticalPosition + 15 * py));
		}
		#endregion

		void lineCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
			Canvas item = sender as Canvas;
			RemoveHighlight();
			SelectedElement = item;
			Line line = item.Children[0] as Line;
			line.Stroke = highlightedBrush;
		}

		private void Button_Click(object sender, RoutedEventArgs e) {
			if (!String.IsNullOrEmpty(StartState)) {
				popup.StartState.IsChecked = false;
			}

			popup.Height = App.Current.Host.Content.ActualHeight;
			popup.Width = App.Current.Host.Content.ActualWidth;
			GeneralTransform gt = this.TransformToVisual(Application.Current.RootVisual as UIElement);
			Point offset = gt.Transform(new Point(0, 0));

			popup.SetValue(Canvas.TopProperty, -offset.Y);
			popup.SetValue(Canvas.LeftProperty, -offset.X);
			popup.SetValue(Canvas.ZIndexProperty, 15);
			popup.Visibility = Visibility.Visible;
		}

		private void RemoveElement_Click(object sender, RoutedEventArgs e) {
			if (SelectedElement is ModelNode) {
				var model = SelectedElement as ModelNode;
				List<ModelEdge> toRemove = new List<ModelEdge>();
				foreach (var item in graph.Edges) {
					Boolean remove = false;

					if (item.Source == model.node.Id) {
						remove = true;
					}

					if (item.Target == model.node.Id) {
						remove = true;
					}

					if (remove) {

						foreach (var elem in rootCanvas.Children) {
							if (elem is ModelEdge) {
								var edge = elem as ModelEdge;
								if (edge.edge == item && !toRemove.Contains(edge)) {
									toRemove.Add(edge);
								}
							}
						}


					}
				}

				foreach (var elem in toRemove) {
					RemoveLine(elem);
				}

				graph.Vertices.Remove(model.node);
				rootCanvas.Children.Remove(model);
			}
			if (SelectedElement is ModelEdge) {
				//Line
				var canvas = SelectedElement as ModelEdge;
				RemoveLine(canvas);
			}
		}

		private void RemoveLine(ModelEdge canvas) {
			var line = canvas.line;

			rootCanvas.Children.Remove(canvas);

			foreach (var item in rootCanvas.Children) {
				if (item is ModelNode) {
					ModelNode model = item as ModelNode;
					foreach (var connectorTOCheck in model.connectors) {
						connectorTOCheck.lines.Remove(canvas);
					}
				}
			}

			graph.Edges.Remove(canvas.edge);
		}

		private Connector CreateConnector(int selectorHeight, int selectorWidth) {
			Connector selectorCanvas = new Connector() {
				Height = selectorHeight,
				Width = selectorWidth
			};
			Border selectorBorder = new Border() {
				Width = selectorWidth,
				Height = selectorHeight,
				BorderThickness = new Thickness(1),
				BorderBrush = new SolidColorBrush(Colors.Black)
			};
			Line selectorHorizontalLine = new Line() {
				Stroke = new SolidColorBrush(Colors.Black),
				StrokeThickness = 1.0,
				X1 = 1.0,
				X2 = selectorHeight - 1.0,
				Y1 = selectorWidth / 2.0,
				Y2 = selectorWidth / 2
			};

			Line selectorVerticallLine = new Line() {
				Stroke = new SolidColorBrush(Colors.Black),
				StrokeThickness = 1.0,
				X1 = selectorHeight / 2.0,
				X2 = selectorHeight / 2.0,
				Y1 = 1.0,
				Y2 = selectorWidth - 1.0
			};
			selectorCanvas.Children.Add(selectorBorder);
			selectorCanvas.Children.Add(selectorHorizontalLine);
			selectorCanvas.Children.Add(selectorVerticallLine);

			selectorCanvas.MouseLeftButtonDown += new MouseButtonEventHandler(selectorCanvas_MouseLeftButtonDown);
			selectorCanvas.MouseLeftButtonUp += new MouseButtonEventHandler(selectorCanvas_MouseLeftButtonUp);
			selectorCanvas.MouseEnter += new MouseEventHandler(selectorCanvas_MouseEnter);
			selectorCanvas.MouseLeave += new MouseEventHandler(selectorCanvas_MouseLeave);

			return selectorCanvas;
		}

		private Canvas CreateRectangleWithTitle(String name, Color color) {
			LinearGradientBrush myHorizontalGradient = GetGradient(color);
			Brush projBrush = myHorizontalGradient;

			Brush textColor = new SolidColorBrush(Colors.Black);
			TextBlock title = new TextBlock() {
				Foreground = textColor,
				Text = name,
				FontSize = 12
			};

			double Height = 25d;
			double Width = (title.ActualWidth + 4) < Height ? Height : title.ActualWidth + 4;
			Width += 4;

			Canvas RectWithTitle = new Canvas() {
				Width = Width,
				Height = Height
			};

			Rectangle nodeBkg = new Rectangle() {
				Width = Width,
				Height = Height,
				Fill = projBrush,
				Stroke = normalBrush
			};

			nodeBkg.RadiusX = 10;
			nodeBkg.RadiusY = 10;

			RectWithTitle.Children.Add(nodeBkg);
			RectWithTitle.Children.Add(title);

			double left = (nodeBkg.Width - title.ActualWidth) / 2;
			double top = (nodeBkg.Height - title.ActualHeight) / 2;
			title.SetValue(Canvas.LeftProperty, left);
			title.SetValue(Canvas.TopProperty, top);

			return RectWithTitle;
		}

		private static LinearGradientBrush GetGradient(Color second) {
			GradientStopCollection GradientStops = new GradientStopCollection();
			LinearGradientBrush myHorizontalGradient = new LinearGradientBrush();
			myHorizontalGradient.StartPoint = new Point(0.5, 0);
			myHorizontalGradient.EndPoint = new Point(0.5, 1);
			myHorizontalGradient.GradientStops.Add(new GradientStop() {
				Color = second,
				Offset = 1.0
			});
			myHorizontalGradient.GradientStops.Add(new GradientStop() {
				Color = Colors.White,
				Offset = 0.1
			});
			return myHorizontalGradient;
		}

		private void RemoveHighlight() {
			if (SelectedElement != null) {
				if (SelectedElement is ModelNode) {
					ModelNode model = SelectedElement as ModelNode;
					model.border.Stroke = normalBrush;
				}
				if (SelectedElement is ModelEdge) {
					//LIne
					ModelEdge item = SelectedElement as ModelEdge;
					Line line = item.line;
					line.Stroke = normalBrush;
				}
			}
		}

		private void Save_Click(object sender, RoutedEventArgs e) {
			GraphML = CreateGraphML();
			exportToDatabase.IsEnabled = true;
			WizardMenu.PopUp.btnOk.IsEnabled = true;
		}

		private void ExportToDatabase_Click(object sender, RoutedEventArgs e) {
			export.Height = App.Current.Host.Content.ActualHeight;
			export.Width = App.Current.Host.Content.ActualWidth;
			GeneralTransform gt = this.TransformToVisual(Application.Current.RootVisual as UIElement);
			Point offset = gt.Transform(new Point(0, 0));

			export.SetValue(Canvas.TopProperty, -offset.Y);
			export.SetValue(Canvas.LeftProperty, -offset.X);
			export.SetValue(Canvas.ZIndexProperty, 15);
			export.Visibility = Visibility.Visible;
		}
	}
}